#include <WProgram.h>
#include <stdint.h>
#include "maxim.h"
#include "PrintBuf.h"
#include "utils.h"
#include "registers.h"
#include "packdata.h"


/**
 This function monitors the batteries during discharge.
 Algorithm:
 . read Status.
 . check for UnderVoltage. (and others if need be)
 . if UV do ADC for cell. measure lowest voltage and display
 . else every so often, read all cells and display voltages (min,avg,pack)

 BUGBUG: should replace Serial.print w/LCD prints
 
 **/

// Last Time we displayed voltage stats
static unsigned long lastDisplayTime = 0;
static uint32_t displayFreqMs = DISPLAY_FREQUENCY_MS;

void setDisplayFreqMs(uint32_t df)
{
  displayFreqMs = df;
}

boolean isDisplayTime()
{
  unsigned long now = millis();
  if (lastDisplayTime + displayFreqMs < now ||
      lastDisplayTime == 0 ||      // uninitialized
      now < lastDisplayTime        // rollover after 50days
      ) {
    return true;
  } else {
    return false;
  }
}

void dcmon(PackData* packData)
{
  if (!packData->scan()) {
    PrintBuf::singleton()->add("Scan start!");
    PrintBuf::singleton()->print();
    return;
  }

  if (packData->isDeviceUV()) {
    // found a device with a low voltage condition
    PrintBuf::singleton()->add("UV Warning!");
    PrintBuf::singleton()->print();

    if (!packData->readCellVoltages()) {
      PrintBuf::singleton()->add("Read Cell V!");
      PrintBuf::singleton()->print();
      return;
    }
    // Print all UV cells
    packData->printUVcellVoltages();

  } else {
    // No alerts.
    // check if time to scan voltages & print interesting
    // data.
    
    if (isDisplayTime()) {
      if (!packData->readCellVoltages()) {
	PrintBuf::singleton()->add("Read Cell V!");
	PrintBuf::singleton()->print();
        return;
      }
      packData->printCellVoltages();
      lastDisplayTime = millis();
    }
  }
}
